use derive_builder::Builder;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

use crate::modeling::Value;

use super::{WorkflowBlockChain, WorkflowDocument, WorkflowResult};

#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder, PartialEq)]
#[builder(name = "WorkflowEngineRunOptionsBuilder")]
#[builder(pattern = "mutable")]
#[builder(setter(into, strip_option), default)]
#[builder(derive(Debug))]
#[builder(build_fn(error = "anyhow::Error"))]
pub struct WorkflowEngineRunOptions {
    pub debug: Option<bool>,
    pub timeout: Option<u64>,
}

#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]

pub struct WorkflowEngineCompileOptions {}

#[async_trait::async_trait]
pub trait WorkflowEngine {
    /// 运行，并返回ID
    async fn run_with_document(
        &self,
        document: WorkflowDocument,
        args: HashMap<String, Value>,
        compile_options: WorkflowEngineCompileOptions,
        run_options: WorkflowEngineRunOptions,
    ) -> anyhow::Result<String>;

    /// 运行，并返回ID
    async fn run(
        &self,
        document: WorkflowBlockChain,
        args: HashMap<String, Value>,
        options: WorkflowEngineRunOptions,
    ) -> anyhow::Result<String>;

    /// 获取结果
    async fn result(&self, id: &String, remove: bool) -> anyhow::Result<Option<WorkflowResult>>;

    /// 获取结果
    async fn result_with_timeout(
        &self,
        id: &String,
        remove: bool,
        timeout: u64,
    ) -> anyhow::Result<WorkflowResult>;

    /// 运行并获取结果
    async fn fetch(
        &self,
        document: WorkflowDocument,
        args: HashMap<String, Value>,
        compile_options: WorkflowEngineCompileOptions,
        run_options: WorkflowEngineRunOptions,
    ) -> anyhow::Result<WorkflowResult>;

    /// 根据数据库获取到元数据
    async fn compile(
        &self,
        document: WorkflowDocument,
        options: WorkflowEngineCompileOptions,
    ) -> anyhow::Result<WorkflowBlockChain>;
}
